package interfaces;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.WindowConstants;

import dinnerSimulation.AbstractAgent;
import dinnerSimulation.AgentCiccio;
import dinnerSimulation.AgentCiccioD_2;
import dinnerSimulation.AgentCiccioD_3;
import dinnerSimulation.AgentCiccioOne;
import dinnerSimulation.AgentCiccioD_1;
import dinnerSimulation.Environment;
import dinnerSimulation.Floor;
import dinnerSimulation.Square;
import dinnerSimulation.Environment.Type;


/**
 * Graphic interface, allow to create the environment configuration
 * and display the sequence of actions performed by the agent
 *
 */
public class MainJFrame extends javax.swing.JFrame
{

    private static final long serialVersionUID = 1L;
    private JMenuBar jMenuBar;
    private JMenu menuFile;
    private JMenuItem closeMenuItem;
    private JMenuItem	openMenuItem;

    public GridPanel gridPanel;
    private SettingsPanel settingsPanel;

    int size = 5;

    public Environment env;
    AgentCiccio agent;
    protected boolean stopped = true;
    private JMenuItem	saveMenuItem;

    public static void main(String[] args)
    {
        new MainJFrame();

    }

    public MainJFrame()
    {
        super();
        initGUI();
    }

    /**
     * Generate a default configuration
     * 		Set the display Layout and menu component.
     * 		Create a default configuration, set the agent on position 0,0
     * 		and the environment as static.
     */
    private void initGUI()
    {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
//		setResizable(false);
        {
            jMenuBar = new JMenuBar();
            setJMenuBar(jMenuBar);
            {
                menuFile = new JMenu();
                jMenuBar.add(menuFile);
                menuFile.setText("File");
                {
                    openMenuItem = new JMenuItem();
                    openMenuItem.setText("Open");
                    openMenuItem.addActionListener(new ActionListener()
                    {
                        @Override
                        public void actionPerformed(ActionEvent e)
                        {
                            Serializzatore<Floor> serializzatore = new Serializzatore<Floor>();
                            Floor floor = serializzatore.carica();
                            if (floor != null)
                            {
                                env.floor.load(floor);
                                remove(gridPanel);
                                gridPanel = new GridPanel(env);
                                getContentPane().add(gridPanel, BorderLayout.EAST);
                                pack();
                            }
                            serializzatore.dispose();
                        }
                    });
                    saveMenuItem = new JMenuItem();
                    saveMenuItem.setText("Save");
                    saveMenuItem.addActionListener(new ActionListener()
                    {
                        @Override
                        public void actionPerformed(ActionEvent e)
                        {
                            Serializzatore<Floor> serializzatore = new Serializzatore<Floor>();
                            serializzatore.salva(env.floor);
                            serializzatore.dispose();
                        }
                    });
                    closeMenuItem = new JMenuItem();
                    closeMenuItem.setText("Close");
                    closeMenuItem.addActionListener(new ActionListener()
                    {
                        @Override
                        public void actionPerformed(ActionEvent e)
                        {
                            System.exit(0);
                        }
                    });
                    menuFile.add(openMenuItem);
                    menuFile.add(saveMenuItem);
                    menuFile.addSeparator();
                    menuFile.add(closeMenuItem);
                }
            }
        }


        //Setting of enviroment, static by default

        agent = new AgentCiccioOne(-1, -1,  200);
        env = new Environment(size, (AgentCiccio) agent,Environment.Type.STATIC );

        settingsPanel = new SettingsPanel(this);
        getContentPane().add(settingsPanel, BorderLayout.WEST);

        gridPanel = new GridPanel(env);
        getContentPane().add(gridPanel, BorderLayout.EAST);

        pack();
        this.setVisible(true);
    }
    /**
     * Execute a loop until the goal is reached and
     * the max number of step (opBound) is not reached
     */
    public void mainLoop(int speed)
    {
        env.show();
        agent.actionList.clear();
        System.out.println("goal reached " + agent.goalReached());
        System.out.println("stopped " + stopped);
        System.out.println("energy " + agent.energy);
        env.agent.setStepValue(settingsPanel.getStepValue());
        while(!agent.goalReached() && !stopped && agent.energy>0)
        {
            System.out.println("ENERGY = " + agent.energy);
            agent.energy--;
            env.update();
            env.show();
            gridPanel.update();
            settingsPanel.update();
            System.out.println("-------------------");
            try
            {
                Thread.sleep(200/(speed+1));
                System.out.println("wait" + speed);
            }
            catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        stopped = true;
        settingsPanel.update();
        System.out.println("Num actions: " + agent.actionList.size());
        agent.showActions();
        //	System.out.println("Performance: " + env.performanceMeasure() );
        System.out.println("-- End --");
    }

    /**
     * Execute only a loop
     */
    
 
    public void mainLoopOnes()
    {
        System.out.println("show..");
        env.show();
        if(!agent.goalReached())
        {
            env.update();
            env.show();
            gridPanel.update();
            settingsPanel.update();
            System.out.println("-------------------");
        }
        System.out.println("Num actions: " + agent.actionList.size());
        agent.showActions();
        //System.out.println("Performance: " + env.performanceMeasure() );
        System.out.println("-- End --");
    }

    
    /**
     * Create a new configuration according of environment
     */
    public void newConfig(int newSize, Environment.Type envType, int steps, int kValue, boolean generated)
    {
    	
    	Floor temp = new Floor(newSize);
        System.out.println("Received size: " + newSize);
      
        System.out.print("tipo ambiente" + envType);
        System.out.println("refresh" + generated);
    
        if(generated){
        	temp = env.floor; //save the floor that was generated by the user
        	
        }
               
        if(envType.toString().equals("DYNAMIC_1")){
        	agent = new AgentCiccioD_1(agent.x, agent.y, steps);
        	agent.kValue = kValue;
        	
        	//agent.setKValue(kValue);
        	
        	
        	System.err.println("%%%%%%%%%%%%%% dinamico 1%%%%%%% agent.kValue = " + agent.kValue);
        	
        	
            /* env.floor = new Floor(newSize);
        	 env.agent = (AgentCiccioD_1) agent; // agente DINAMICO
        	 env.agent.kValue = kValue;
        	 env.type = ;
        	 env.k = 1;
        	 env.start = false;*/
        	 env = new Environment(newSize, (AgentCiccioD_1) agent, envType);
        }
        if(envType.toString().equals("STATIC")){
        	agent = new AgentCiccioOne(agent.x, agent.y, steps);
        	System.err.println("%%%%%%%%%% Statico %%%%%%%%%%%" );
          // env.floor = new Floor(newSize);
     	   env.agent = (AgentCiccioOne) agent;// agente STATICO
     	   env.type = envType;
     }
        
        if(envType.toString().equals("DYNAMIC_2")){
        	agent = new AgentCiccioD_2(agent.x, agent.y, steps);
        	agent.kValue = kValue;

        	
        	System.err.println("%%%%%%%%%%%%%% dinamico 2 %%%%%%% agent.kValue = " + agent.kValue);
       
        	 env = new Environment(newSize, (AgentCiccioD_2) agent, envType);
        
        }
        
        if(envType.toString().equals("DYNAMIC_3")){
        	agent = new AgentCiccioD_3(agent.x, agent.y, steps);
        	agent.kValue = kValue;

        	
        	System.err.println("%%%%%%%%%%%%%% dinamico 3 %%%%%%% agent.kValue = " + agent.kValue);
       
        	 env = new Environment(newSize, (AgentCiccioD_3) agent, envType);
        
        }
        
        System.out.println("New confg ENV settings" + env.floor.length+ " " +env.floor.width + "boolean"+gridPanel.isAllSelected() );
          
        if(generated){
        	env.floor= temp;
        }
        else{
        	getContentPane().remove(gridPanel);
        	gridPanel = new GridPanel(env);
        	getContentPane().add(gridPanel, BorderLayout.EAST);
        	gridPanel.update();
        	pack();
        	}
         
     }
    


}
